#include <pthread.h>
#include <iostream>
#include <map>
#include <string>
#include <string.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <mysql++.h>
#include "CommFormat.h"
#include "Serialization.h"
#include "socket_lib/ClientSocket.h"
#include "socket_lib/SocketException.h"
#include "thread_func/timer.h"
#include "db_operation/DbOperation.h"

#include <sys/stat.h>   //mkfifo()
#include <fcntl.h>      //O_WRONLY O_RDONLY
#include <stdlib.h>	//exit()

#define FIFOPATH1 "/home/xbq/dev/test/2select/fifo1"
//#define FIFOPATH2 "/home/xbq/dev/test/select/fifo2"
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)

using namespace std;

void* select_thread (void*)
{
	int readfd;
	fd_set fdset;
	int maxfdp1, sel;
	string buff;

	try 
	{
		//send2db(buff);
		//*
		if ( (readfd = open(FIFOPATH1, O_RDONLY | O_NONBLOCK)) < 0)
		{
			perror ("error: ");
		}
		//*/

		ClientSocket cli_sock1("2001:da8:bf:0:a5d5:205b:3a2c:cdc", 2000);
		cli_sock1.sock_nonblock(true);
		sleep(1);
		//ClientSocket cli_sock2("192.168.237.57", 2000);
		//cli_sock2.set_nonblock(true);

		struct ReqCtrlMsg rcm;
		memset(&rcm, 0, 4);
		rcm.type = 1;
		rcm.resp = 1;
		rcm.vlink_num = 0;
		rcm.stat = 0;
		cout << sizeof(struct VrConfPkt) << endl;
		
		struct VrConfPkt vcp;
		memset(&vcp, 0, 31);
		vcp.type = 2;
		vcp.oper = 1;
		vcp.vlink_param.vlink_no = 1;
		vcp.vlink_param.hello_interval = 3;
		vcp.vlink_param.local_ip_addr = 1;
		vcp.vlink_param.peer_ip_addr = 0xffffffff;
		vcp.vlink_param.vr_addr.__in6_u.__u6_addr32[0] = 0x000005ff;
		vcp.vlink_param.vr_addr.__in6_u.__u6_addr32[1] = 0x0;
		vcp.vlink_param.vr_addr.__in6_u.__u6_addr32[2] = 0x0;
		vcp.vlink_param.vr_addr.__in6_u.__u6_addr32[3] = 0xb9000000;
		
		cli_sock1 << rcm_serial(rcm);
		cli_sock1 << vcp_serial(vcp);
		
		//cout << sizeof(fdset) << endl;
		//cout << FD_SETSIZE << endl;

		cout << __LINE__ << endl;
		FD_ZERO(&fdset);

		while (true)
		{
			FD_SET(cli_sock1.sockfd(), &fdset);
			//FD_SET(cli_sock2.sockfd(), &fdset);
			FD_SET(readfd, &fdset);
			//maxfdp1 = max( readfd, max(cli_sock1.sockfd(), cli_sock2.sockfd())) + 1;
			maxfdp1 = max(cli_sock1.sockfd(), readfd) + 1;
			cout << "maxfdp1: " << maxfdp1 << endl;

			if ( (sel = select(maxfdp1, &fdset, NULL, NULL, NULL)) < 0)
			{
				perror("select error: ");
				exit(1);
			}
			cout << sel << endl;

			if ( FD_ISSET(cli_sock1.sockfd(), &fdset) )
			{
				cli_sock1 >> buff;
				cout << buff << "in boject 1." << endl;
				if (3 == buff[0])
				{
					cout << "This is VlinkInfoMsg. The buff size is:" << buff.size() << endl;
					send2db(vcp.vlink_param.vr_addr, buff);
				}
				else if (4 == buff[0])
				{
					cout << "This is VlinkPathMsg. The buff size is: " << buff.size() << endl;
					send2db(vcp.vlink_param.vr_addr, buff);
				}
				else
				{
					cout << "This is not msg." << buff.size() << endl;
				}
			}
			//if ( FD_ISSET(cli_sock2.sockfd(), &fdset) )
			{
				//cli_sock2 >> buff;
				//cout << buff << "2" << endl;
			}
			//*
			if ( FD_ISSET(readfd, &fdset) )
			{
				cout << "5 sec passed." << endl;
				//read(readfd, );
			}
			//*/
		}
	}
	catch (SocketException& e)
	{
		cout << "Exception was caught: " << e.description() << endl;
	}
}

int main (void)
{
	pthread_t tid1, tid2;
	char timer_over_msg[] = "the timer failed to create.";
	struct tm* nowtime;
	char tmp[15];
	//int t = time(NULL);
	int t = 1234567890;
	nowtime = localtime((const time_t*)&t);
	strftime(tmp, 30, "%F%T", nowtime);
	cout << tmp << endl;

	cout << "now time is : " << t << endl;

	mkfifo(FIFOPATH1, FILE_MODE);
	pthread_create(&tid1, NULL, select_thread, NULL);
	//pthread_create(&tid2, NULL, timer_thread, timer_over_msg);
	pthread_join(tid1, 0);
	//pthread_join(tid2, 0);
	unlink(FIFOPATH1);
	return 0;
}

